<template>
  <n-layout position="absolute">
    <n-layout-content>
      <n-form
          ref="formRef"
          :model="goodsDetail"
          :rules="rules"
          label-placement="left"
          label-width="120"
          require-mark-placement="right-hanging"
          style="margin: 20px 20px 100px 20px;"
      >
        <div class="block">
          <div class="block__title">基本信息</div>
          <div class="block__content">
            <div :style="{maxWidth: '640px'}">
              <n-form-item label="商品名称" path="goodsName">
                <n-input v-model:value="goodsDetail.goodsName" clearable show-count/>
              </n-form-item>
              <n-form-item label="商品卖点" path="sellingPoint">
                <n-input v-model:value="goodsDetail.sellingPoint" type="textarea" clearable show-count/>
              </n-form-item>
              <n-form-item label="分类" path="categoryId3">
                <n-text v-if="displaySelectedCategory">{{ displaySelectedCategory }}</n-text>
                <n-cascader v-else
                            placeholder="选择商品分类"
                            :expand-trigger="'click'"
                            :options="goodsCateList"
                            :check-strategy="'child'"
                            :show-path="true"
                            :filterable="true"
                            remote
                            :on-load="getGoodsCateList"
                            v-model:value="goodsDetail.categoryId3"
                />
              </n-form-item>
              <n-form-item label="主图" path="mainImgUrls">
                <n-space vertical>
                  <n-text depth="3">最多可以上传12张图片，建议尺寸800*800px，大小1M内</n-text>
                  <x-upload :limit="12" :urls="goodsDetail.mainImgUrls" @change="changeMainImg"/>
                </n-space>
              </n-form-item>
            </div>
          </div>
        </div>
        <div class="block">
          <div class="block__title">商品详情</div>
          <div class="block__content">
            <div class="container">
              <n-text depth="3">详情介绍商品以提升转化。若未编辑，商品发布后轮播图将自动填充至图文详情</n-text>
              <div class="content flex top">
                <div class="preview">
                  <div class="title">页面详情预览</div>
                  <n-scrollbar class="preview__scrollbar" style="height: 580px">
                    <template v-if="goodsDetail.contentImgUrls && goodsDetail.contentImgUrls.length > 0">
                      <div v-for="(pic, picIndex) in goodsDetail.contentImgUrls" :key="picIndex">
                        <img :src="pic" alt="" style="width: 100%; pointer-events: none"/>
                      </div>
                    </template>
                    <div v-else class="empty">
                      <n-space vertical align="center">
                        <x-empty size="huge" description="暂未编辑详情"/>
                        <n-text depth="3">编辑商品详情，提升商品转化率</n-text>
                      </n-space>
                    </div>
                  </n-scrollbar>
                </div>
                <n-form-item :show-feedback="false" style="flex: 1">
                  <div class="detail-container">
                    <n-space align="center" style="margin-bottom: 5px">
                      <n-text depth="3">
                        最多可添加50张图片，已添加
                        <n-text type="warning">{{
                            goodsDetail.contentImgUrls ? goodsDetail.contentImgUrls.length : 0
                          }}
                        </n-text>
                        / 50
                      </n-text>
                    </n-space>
                    <div ref="detailBoxRef" class="detail-box">
                      <x-upload :limit="50"
                                :urls="goodsDetail.contentImgUrls ? goodsDetail.contentImgUrls : []"
                                @change="changeContentImg"/>
                    </div>
                  </div>
                </n-form-item>
              </div>
            </div>
          </div>
        </div>
        <div class="block">
          <div class="block__title">库存规格</div>
          <div class="block__content">
            <n-alert type="warning" style="margin-bottom: 10px">
              请如实填写库存信息，以确保商品可以在承诺发货时间内发出，避免可能的物流违规
            </n-alert>

            <n-form-item label="商品规格">
              <div style="width:100%;background:#ffffff;padding:10px 20px;border-radius:5px">
                <div v-for="(item, index) in goodsDetail.specList" :key="index" class="spec-editor">
                  <div class="spec-editor__left">规格{{ index + 1 }}：</div>
                  <div class="spec-editor__right">
                    <div class="spec-editor__title">
                      <div class="flex">
                        <n-input
                            v-model:value="item.attrName"
                            tag
                            filterable
                            style="width: 500px"
                        />
                      </div>

                      <n-popconfirm placement="left" @positive-click="deleteSpec(index)">
                        <template v-slot:trigger>
                          <n-button type="error" text>删除规格</n-button>
                        </template>
                        删除该规格后，当前的规格相关数据将丢失，确认要删除吗？
                      </n-popconfirm>
                    </div>
                    <div v-if="item.attrName" class="spec-editor__content">
                      <div class="spec-value__list">
                        <div v-for="(spec, specIndex) in item.attrValueList" :key="specIndex" class="spec-value__item">
                          <n-space align="center" vertical>
                            <n-input-group>
                              <n-input
                                  v-model:value="spec.itemName"
                                  autosize
                                  style="min-width: 150px; max-width: 500px"
                                  placeholder="请输入规格值"
                                  round
                                  clearable
                                  maxlength="40"
                                  show-count
                                  @blur="updateSpecValue(spec, item)"
                              />

                              <n-button
                                  style="padding: 0 10px; border-radius: 0 50% 50% 0"
                                  secondary
                                  type="primary"
                                  @click="addSpecValue(specIndex, item.attrValueList)"
                              >
                                <template #icon>
                                  <n-icon>
                                    <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
                                      <path
                                          d="M368.5 240H272v-96.5c0-8.8-7.2-16-16-16s-16 7.2-16 16V240h-96.5c-8.8 0-16 7.2-16 16 0 4.4 1.8 8.4 4.7 11.3 2.9 2.9 6.9 4.7 11.3 4.7H240v96.5c0 4.4 1.8 8.4 4.7 11.3 2.9 2.9 6.9 4.7 11.3 4.7 8.8 0 16-7.2 16-16V272h96.5c8.8 0 16-7.2 16-16s-7.2-16-16-16z"
                                      />
                                    </svg>
                                  </n-icon>
                                </template>
                              </n-button>
                            </n-input-group>

                            <n-button
                                v-if="item.attrValueList.length !== 1"
                                class="btn-delete"
                                secondary
                                circle
                                size="tiny"
                                @click="deleteSpecValue(specIndex, item.itemName, item.attrValueList)"
                            >
                              <template #icon>
                                <n-icon size="14">
                                  <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
                                       viewBox="0 0 32 32">
                                    <path
                                        d="M24 9.4L22.6 8L16 14.6L9.4 8L8 9.4l6.6 6.6L8 22.6L9.4 24l6.6-6.6l6.6 6.6l1.4-1.4l-6.6-6.6L24 9.4z"
                                        fill="currentColor"></path>
                                  </svg>
                                </n-icon>
                              </template>
                            </n-button>
                          </n-space>
                        </div>
                      </div>
                    </div>
                  </div>
                </div>
                <n-space>
                  <n-button v-if="goodsDetail.specList.length < 5"
                            type="primary" secondary size="small" @click="addSpec">
                    添加规格
                  </n-button>
                </n-space>
              </div>
            </n-form-item>

            <n-form-item v-if="goodsDetail.skuList?.length > 0" label="价格与库存">
              <div class="sku-table-box flex column top">
                <div class="table-box" style="width:100%">
                  <div class="table">
                    <div class="thead">
                      <div class="tr">
                        <div class="th">
                          <div class="title">
                            <span class="title_text">规格类型</span>
                          </div>
                        </div>
                        <div class="th">
                          <div class="title">
                            <span class="title_text required">库存</span>
                          </div>
                        </div>
                        <div class="th">
                          <div class="title">
                            <span class="title_text required">商品价格 (元)</span>
                          </div>
                        </div>
                        <div class="th">
                          <div class="title">
                            <span class="title_text">配图</span>
                          </div>
                        </div>
                      </div>
                    </div>
                    <div class="tbody">
                      <n-scrollbar class="preview__scrollbar" style="max-height: 580px">
                        <div v-for="(item, index) in goodsDetail.skuList" :key="item.specValue" class="tr">
                          <div class="td pt-30">
                            <strong>
                              {{ item.specValue }}
                            </strong>
                          </div>
                          <div class="td pt-30">
                            <n-form-item
                                label="库存"
                                :show-label="false"
                                :path="`skuList.${index}.stockNum`"
                                :rule="[
                          {
                            key: 'stockNum',
                            required: true,
                            type: 'number',
                            min: 0,
                            message: '请输入库存数量',
                            trigger: ['blur', 'input']
                          }
                        ]"
                            >
                              <n-input-number v-model:value="item.stockNum" :show-button="false"/>
                            </n-form-item>
                          </div>
                          <div class="td pt-30">
                            <n-form-item
                                label="商品价格"
                                :show-label="false"
                                :path="`skuList.${index}.skuPrice`"
                                :rule="[
                          {
                            key: 'skuPrice',
                            required: true,
                            message: '请输入价格',
                            trigger: ['blur', 'input']
                          },
                          {
                            key: 'skuPrice',
                            pattern: /^(([1-9]{1}\d*)|(0{1}))(\.\d{0,2})?$/,
                            message: '请输入正确金额',
                            trigger: ['blur', 'input']
                          },
                        ]"
                            >
                              <n-input v-model:value="item.skuPrice" :show-button="false" :max="10000000"/>
                            </n-form-item>
                          </div>
                          <div class="td">
                            <x-upload :limit="1" @change="changeSkuImg($event, item)"/>
                          </div>
                        </div>
                      </n-scrollbar>
                    </div>
                  </div>
                </div>
              </div>
            </n-form-item>
            <n-form-item label="商品成本价" path="costPrice">
              <n-space align="center">
                <n-input v-model:value="goodsDetail.goodsPrice" clearable placeholder="应低于商品拼单价"
                         :max="10000000">
                </n-input>
                <n-text depth="3">成本价将用于利润分析、营销建议等</n-text>
              </n-space>
            </n-form-item>

            <n-form-item label="库存扣减方式" path="productSafeguard.stockType">
              <n-radio-group v-model:value="goodsDetail.stockType" name="deliveryType">
                <n-space>
                  <n-radio :value="0">拍下减库存</n-radio>
                  <n-radio :value="1">付款减库存</n-radio>
                </n-space>
              </n-radio-group>
            </n-form-item>

            <n-alert type="info">
              <n-space vertical>
              <span>
                拍下减库存：买家提交订单，扣减库存数量，可能存在恶意占用库存风险，商品参加活动时，默认为付款减库存。
              </span>
                <span>付款减库存：买家支付成功扣减库存数量，可能存在超卖风险。你已设置超卖订单自动退款。</span>
              </n-space>
            </n-alert>
          </div>
        </div>
      </n-form>
    </n-layout-content>

    <n-layout-footer
        bordered
        position="absolute"
        style="padding: 24px; text-align: center;"
    >
      <x-button v-if="route.query.id" @click="handleBack">返 回</x-button>
      <x-button
          type="primary"
          @click="handleSubmit"
      >
        提交
      </x-button>
    </n-layout-footer>
  </n-layout>
</template>

<script setup>
import {useRoute, useRouter} from "vue-router";
import {computed, onBeforeMount, ref} from "vue";
import {
  NAlert,
  NButton,
  NCascader,
  NForm,
  NFormItem,
  NIcon,
  NInput,
  NInputGroup,
  NInputNumber,
  NLayout,
  NLayoutContent,
  NLayoutFooter,
  NPopconfirm,
  NRadio,
  NRadioGroup,
  NScrollbar,
  NSpace,
  NText,
  useMessage
} from 'naive-ui'
import XButton from '@/components/x-button.vue'
import XUpload from '@/components/x-upload.vue'
import XEmpty from '@/components/x-empty.vue'
import {reqGoodsCateList, reqGoodsDetail, reqGoodsEdit, reqGoodsSave,} from "@/api";

const route = useRoute()
const router = useRouter()
const message = useMessage()

const goodsDetail = ref({
  id: null,
  goodsName: '',
  sellingPoint: '',
  mainImgUrls: [],
  goodsPrice: "0",
  initSalesVolume: 0,
  stockType: 0,
  categoryId3: null,
  contentImgUrls: [],
  attrList: [],
  specList: [],
  skuList: [],
})
const goodsCateList = ref([])

const formRef = ref(null)
const rules = ref({
  goodsName: {required: true, message: '请输入商品名称', trigger: ['input', 'blur']},
  mainImgUrls: {required: true, message: '请选择商品主图', trigger: 'change', type: 'array'},
  categoryId3: {required: true, message: '请选择商品分类', trigger: ['blur', 'change'], type: 'number', min: 1},
})

const displaySelectedCategory = computed(() => {
  let name = ''
  if (goodsDetail.value.categoryName1) {
    name += goodsDetail.value.categoryName1
  }
  if (goodsDetail.value.categoryName2) {
    name += ` ＞ ${goodsDetail.value.categoryName2}`
  }
  if (goodsDetail.value.categoryName3) {
    name += ` ＞ ${goodsDetail.value.categoryName3}`
  }
  return name
})

async function getGoodsCateList(option) {
  let parentId = 0, depth = 1
  if (option) {
    parentId = option.value
    depth = option.depth + 1
  }
  const cateList = (await reqGoodsCateList(parentId)).data
  const children = []
  for (let item of cateList) {
    children.push({
      label: item.categoryName,
      value: item.id,
      depth: depth,
      isLeaf: depth === 3
    })
  }
  if (option) {
    option.children = children
  } else {
    goodsCateList.value = children
  }
}

function changeMainImg(value) {
  goodsDetail.value.mainImgUrls = value
}

function changeContentImg(value) {
  goodsDetail.value.contentImgUrls = value
}

function addSpec() {
  goodsDetail.value.specList.push({attrName: "", attrValueList: [{}]})
}

function deleteSpec(index) {
  goodsDetail.value.specList.splice(index, 1)
  parseSku()
}

function addSpecValue(index, attrValueList) {
  if (attrValueList.length > 10) {
    return message.error("最多添加5个规格值")
  }
  attrValueList.splice(index + 1, 0, {itemName: ''})
}

function deleteSpecValue(index, itemName, attrValueList) {
  attrValueList.splice(index, 1)
  parseSku()
}

function updateSpecValue(spec, item) {
  if (!spec.itemName) {
    return
  }
  spec.itemName = spec.itemName.trim()
  let count = 0
  for (let other of item.attrValueList) {
    if (spec.itemName === other.itemName) {
      count++
    }
  }
  if (count > 1) {
    spec.itemName = ""
    parseSku()
    return message.warning('属性值名称之间不能相同')
  }
  parseSku()
}

function parseSku() {
  const skuList = []
  if (goodsDetail.value.specList && goodsDetail.value.specList.length > 0) {
    const res = []
    parseAttr({}, 0, res)
    for (let item of goodsDetail.value.skuList) {
      let index = -1
      for (let i = 0; i < res.length; i++) {
        if (item.specValue === res[i].specValue) {
          item.specIds = res[i].specIds
          index = i
          break
        }
      }
      if (index === -1) {
        continue
      }
      res.splice(index, 1)
      skuList.push(item)
    }
    for (let item of res) {
      skuList.push(item)
    }
  }
  goodsDetail.value.skuList = skuList
}

function parseAttr(prefix, index, res) {
  if (index >= goodsDetail.value.specList.length) {
    res.push(prefix)
    return
  }
  const attr = goodsDetail.value.specList[index++];
  if (!attr.attrValueList) {
    res.push(prefix)
    return
  }
  if (prefix.specValue) {
    prefix.specValue = prefix.specValue + "-" + attr.attrName
  } else {
    prefix.specValue = attr.attrName
  }
  const attrValues = []
  for (let item of attr.attrValueList) {
    if (item.itemName && item.itemName !== "") {
      attrValues.push(item)
    }
  }
  attrValues.sort((v1, v2) => v1.itemName > v2.itemName ? 1 : -1);
  for (let i = 0; i < attrValues.length; i++) {
    attrValues[i].itemId = i + 1
    let specIds = String(i + 1)
    if (prefix.specIds) {
      specIds = prefix.specIds + "_" + String(i + 1)
    }
    parseAttr({
      specIds,
      specValue: prefix.specValue + ":" + attrValues[i].itemName,
    }, index, res)
  }
}

function changeSkuImg(arr, item) {
  if (arr && arr.length > 0) {
    item.skuImgUrl = arr[0]
  }
}

function handleBack() {
  router.back()
}

async function handleSubmit() {
  formRef.value.validate(async errors => {
    if (!errors) {
      if (route.query.id) {
        await reqGoodsEdit(goodsDetail.value)
      } else {
        await reqGoodsSave(goodsDetail.value)
      }
      // 这里可以出一个提示框，等待主从同步
      await router.replace({name: "Goods-List"})
    } else {
      return message.warning(errors[0][0].message)
    }
  })
}

onBeforeMount(async () => {
  if (route.query.id) {
    const resp = await reqGoodsDetail(Number(route.query.id))
    goodsDetail.value = resp.data
  } else {
    await getGoodsCateList()
  }
})
</script>

<style lang="scss" scoped>

.block {
  &__title {
    margin-bottom: 10px;
    font-size: 18px;
  }

  &__content {
    flex: 1;
    padding: 20px;
    background: #f7f8fa;
    border-radius: 10px;
    min-width: 800px;
  }

  + .block {
    margin-top: 30px;
  }
}

.container {
  .content {
    margin-top: 10px;
  }

  .preview {
    flex: none;
    width: 375px;
    border: 1px solid rgba(0, 0, 0, 0.05);
    background: #f7f8fa;
    margin-right: 10px;

    .title {
      padding: 16px;
      background: #ffffff;
      font-weight: 500;
      border-bottom: 1px solid rgba(0, 0, 0, 0.05);
    }

    .empty {
      margin-top: 200px;
    }
  }

  .detail-container {
    padding: 10px;
    width: 100%;
    background: #ffffff;
  }

  .detail-box {
    width: 100%;
    max-height: 580px;
    display: flex;
    flex-direction: column;
    overflow: scroll;
    border-radius: 3px;
  }
}

.module-box {
  & + & {
    margin-top: 20px;
  }
}

.spec-editor {
  display: flex;
  overflow: hidden;
  margin-bottom: 20px;

  &__left {
    padding-top: 6px;
    flex: none;
  }

  &__right {
    flex: 1;
    border: 1px solid rgba(239, 239, 245, 1);
  }

  &__title {
    padding: 6px;
    background: #fafafc;
    border-bottom: 1px solid rgba(239, 239, 245, 1);
    display: flex;
    justify-content: space-between;
  }

  &__content {
    padding: 17px 10px 2px;
    background: #fff;
  }
}

.spec-value {
  &__list {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
  }

  &__item {
    position: relative;
    margin-right: 10px;
    margin-bottom: 10px;

    &:hover {
      .btn-delete {
        visibility: visible;
        opacity: 1;
        transition: 0.3s;
      }
    }
  }
}

.btn-delete {
  position: absolute;
  top: -14px;
  right: -14px;
  opacity: 0;
  visibility: hidden;
  transition: 0.3s;
}

.title {
  .title_text {
    margin-right: 5px;

    &.required {
      &:after {
        content: '*';
        color: #fd494d;
        display: inline-block;
        margin-left: 5px;
      }
    }
  }
}

.sku-table-box {
  width: 100%;
  overflow-x: scroll;
}

.table {
  border: 1px solid #eeeeee;

  .thead {
    background: #fafafc;

    .tr {
      height: 50px;
      font-weight: bold;

      .th {
        display: flex;
        justify-content: center;
        align-items: center;
      }
    }
  }

  .tbody {
    background: #ffffff;

    .pt-30 {
      padding-top: 30px;
    }

    .td {
      display: flex;
      justify-content: center;
    }
  }

  .tr {
    display: flex;
  }

  .td,
  .th {
    flex: 1;
    min-width: 120px;
    padding: 2px 4px;
  }

  .col-spec-name {
    flex: none;
    width: 130px;
  }
}

.batch-edit-box {
  position: sticky;
  left: 0;
  padding: 4px;
}

.scroll-container {
  height: 500px;
}
</style>